package org.budo.mongo.filter;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Spliterator;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import org.bson.Document;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.conversions.Bson;
import org.budo.mongo.wrapper.DBCollectionWrapper;
import org.budo.mongo.wrapper.DBCursorWrapper;
import org.budo.mongo.wrapper.DBWrapper;
import org.budo.mongo.wrapper.MongoCollectionWrapper;
import org.budo.mongo.wrapper.MongoDatabaseWrapper;

import com.mongodb.AggregationOptions;
import com.mongodb.AggregationOutput;
import com.mongodb.BulkWriteOperation;
import com.mongodb.CommandResult;
import com.mongodb.Cursor;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBDecoderFactory;
import com.mongodb.DBEncoder;
import com.mongodb.DBEncoderFactory;
import com.mongodb.DBObject;
import com.mongodb.GroupCommand;
import com.mongodb.InsertOptions;
import com.mongodb.MapReduceCommand;
import com.mongodb.MapReduceCommand.OutputType;
import com.mongodb.MapReduceOutput;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoNamespace;
import com.mongodb.MongoOptions;
import com.mongodb.ParallelScanOptions;
import com.mongodb.ReadConcern;
import com.mongodb.ReadPreference;
import com.mongodb.ReplicaSetStatus;
import com.mongodb.ServerAddress;
import com.mongodb.WriteConcern;
import com.mongodb.WriteResult;
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.DistinctIterable;
import com.mongodb.client.FindIterable;
import com.mongodb.client.ListCollectionsIterable;
import com.mongodb.client.ListDatabasesIterable;
import com.mongodb.client.ListIndexesIterable;
import com.mongodb.client.MapReduceIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;
import com.mongodb.client.model.BulkWriteOptions;
import com.mongodb.client.model.Collation;
import com.mongodb.client.model.CountOptions;
import com.mongodb.client.model.CreateCollectionOptions;
import com.mongodb.client.model.CreateViewOptions;
import com.mongodb.client.model.DBCollectionCountOptions;
import com.mongodb.client.model.DBCollectionDistinctOptions;
import com.mongodb.client.model.DBCollectionFindAndModifyOptions;
import com.mongodb.client.model.DBCollectionFindOptions;
import com.mongodb.client.model.DBCollectionRemoveOptions;
import com.mongodb.client.model.DBCollectionUpdateOptions;
import com.mongodb.client.model.DBCreateViewOptions;
import com.mongodb.client.model.DeleteOptions;
import com.mongodb.client.model.FindOneAndDeleteOptions;
import com.mongodb.client.model.FindOneAndReplaceOptions;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.model.InsertManyOptions;
import com.mongodb.client.model.InsertOneOptions;
import com.mongodb.client.model.RenameCollectionOptions;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" })
public class MongoFilterChainImpl implements MongoFilterChain {
    private List<MongoFilter> filters;

    private Integer position;

    public MongoFilterChainImpl(List<MongoFilter> filters) {
        this.filters = filters;
        this.position = 0;
    }

    @Override
    public synchronized void mongoClient_addOption(MongoClient mongoClient, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoClient_addOption(this, mongoClient, $0);
        } else {
            this.position = 0;
            mongoClient.addOption($0);
        }
    }

    @Override
    public synchronized void mongoClient_close(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoClient_close(this, mongoClient);
        } else {
            this.position = 0;
            mongoClient.close();
        }
    }

    @Override
    public synchronized void mongoClient_dropDatabase(MongoClient mongoClient, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoClient_dropDatabase(this, mongoClient, $0);
        } else {
            this.position = 0;
            mongoClient.dropDatabase($0);
        }
    }

    @Override
    public synchronized CommandResult mongoClient_fsync(MongoClient mongoClient, boolean $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_fsync(this, mongoClient, $0);
        } else {
            this.position = 0;
            return mongoClient.fsync($0);
        }
    }

    @Override
    public synchronized CommandResult mongoClient_fsyncAndLock(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_fsyncAndLock(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.fsyncAndLock();
        }
    }

    @Override
    public synchronized ServerAddress mongoClient_getAddress(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getAddress(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getAddress();
        }
    }

    @Override
    public synchronized List mongoClient_getAllAddress(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getAllAddress(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getAllAddress();
        }
    }

    @Override
    public synchronized String mongoClient_getConnectPoint(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getConnectPoint(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getConnectPoint();
        }
    }

    @Override
    public synchronized List mongoClient_getCredentialsList(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getCredentialsList(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getCredentialsList();
        }
    }

    @Override
    public synchronized DB mongoClient_getDB(MongoClient mongoClient, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getDB(this, mongoClient, $0);
        } else {
            this.position = 0;
            DB _db = mongoClient.getDB($0);
            return new DBWrapper(this.getFilters(), _db, _db.getMongo(), _db.getName());
        }
    }

    @Override
    public synchronized MongoDatabase mongoClient_getDatabase(MongoClient mongoClient, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getDatabase(this, mongoClient, $0);
        } else {
            this.position = 0;
            return new MongoDatabaseWrapper(this.getFilters(), mongoClient.getDatabase($0));
        }
    }

    @Override
    public synchronized List mongoClient_getDatabaseNames(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getDatabaseNames(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getDatabaseNames();
        }
    }

    @Override
    public synchronized int mongoClient_getMaxBsonObjectSize(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getMaxBsonObjectSize(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getMaxBsonObjectSize();
        }
    }

    @Override
    public synchronized MongoClientOptions mongoClient_getMongoClientOptions(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getMongoClientOptions(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getMongoClientOptions();
        }
    }

    @Override
    public synchronized MongoOptions mongoClient_getMongoOptions(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getMongoOptions(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getMongoOptions();
        }
    }

    @Override
    public synchronized int mongoClient_getOptions(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getOptions(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getOptions();
        }
    }

    @Override
    public synchronized ReadConcern mongoClient_getReadConcern(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getReadConcern(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getReadConcern();
        }
    }

    @Override
    public synchronized ReadPreference mongoClient_getReadPreference(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getReadPreference(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getReadPreference();
        }
    }

    @Override
    public synchronized ReplicaSetStatus mongoClient_getReplicaSetStatus(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getReplicaSetStatus(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getReplicaSetStatus();
        }
    }

    @Override
    public synchronized List mongoClient_getServerAddressList(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getServerAddressList(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getServerAddressList();
        }
    }

    @Override
    public synchronized Collection mongoClient_getUsedDatabases(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getUsedDatabases(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getUsedDatabases();
        }
    }

    @Override
    public synchronized WriteConcern mongoClient_getWriteConcern(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_getWriteConcern(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.getWriteConcern();
        }
    }

    @Override
    public synchronized boolean mongoClient_isLocked(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_isLocked(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.isLocked();
        }
    }

    @Override
    public synchronized MongoIterable mongoClient_listDatabaseNames(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_listDatabaseNames(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.listDatabaseNames();
        }
    }

    @Override
    public synchronized ListDatabasesIterable mongoClient_listDatabases(MongoClient mongoClient, Class $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_listDatabases(this, mongoClient, $0);
        } else {
            this.position = 0;
            return mongoClient.listDatabases($0);
        }
    }

    @Override
    public synchronized ListDatabasesIterable mongoClient_listDatabases(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_listDatabases(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.listDatabases();
        }
    }

    @Override
    public synchronized void mongoClient_resetOptions(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoClient_resetOptions(this, mongoClient);
        } else {
            this.position = 0;
            mongoClient.resetOptions();
        }
    }

    @Override
    public synchronized void mongoClient_setOptions(MongoClient mongoClient, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoClient_setOptions(this, mongoClient, $0);
        } else {
            this.position = 0;
            mongoClient.setOptions($0);
        }
    }

    @Override
    public synchronized void mongoClient_setReadPreference(MongoClient mongoClient, ReadPreference $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoClient_setReadPreference(this, mongoClient, $0);
        } else {
            this.position = 0;
            mongoClient.setReadPreference($0);
        }
    }

    @Override
    public synchronized void mongoClient_setWriteConcern(MongoClient mongoClient, WriteConcern $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoClient_setWriteConcern(this, mongoClient, $0);
        } else {
            this.position = 0;
            mongoClient.setWriteConcern($0);
        }
    }

    @Override
    public synchronized void mongoClient_slaveOk(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoClient_slaveOk(this, mongoClient);
        } else {
            this.position = 0;
            mongoClient.slaveOk();
        }
    }

    @Override
    public synchronized String mongoClient_toString(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_toString(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.toString();
        }
    }

    @Override
    public synchronized DBObject mongoClient_unlock(MongoClient mongoClient) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoClient_unlock(this, mongoClient);
        } else {
            this.position = 0;
            return mongoClient.unlock();
        }
    }

    @Override
    public synchronized void db_addOption(DB db, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.db_addOption(this, db, $0);
        } else {
            this.position = 0;
            db.addOption($0);
        }
    }

    @Override
    public synchronized WriteResult db_addUser(DB db, String $0, char[] $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_addUser(this, db, $0, $1);
        } else {
            this.position = 0;
            return db.addUser($0, $1);
        }
    }

    @Override
    public synchronized WriteResult db_addUser(DB db, String $0, char[] $1, boolean $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_addUser(this, db, $0, $1, $2);
        } else {
            this.position = 0;
            return db.addUser($0, $1, $2);
        }
    }

    @Override
    public synchronized boolean db_collectionExists(DB db, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_collectionExists(this, db, $0);
        } else {
            this.position = 0;
            return db.collectionExists($0);
        }
    }

    @Override
    public synchronized CommandResult db_command(DB db, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_command(this, db, $0);
        } else {
            this.position = 0;
            return db.command($0);
        }
    }

    @Override
    public synchronized CommandResult db_command(DB db, DBObject $0, DBEncoder $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_command(this, db, $0, $1);
        } else {
            this.position = 0;
            return db.command($0, $1);
        }
    }

    @Override
    public synchronized CommandResult db_command(DB db, DBObject $0, ReadPreference $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_command(this, db, $0, $1);
        } else {
            this.position = 0;
            return db.command($0, $1);
        }
    }

    @Override
    public synchronized CommandResult db_command(DB db, DBObject $0, ReadPreference $1, DBEncoder $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_command(this, db, $0, $1, $2);
        } else {
            this.position = 0;
            return db.command($0, $1, $2);
        }
    }

    @Override
    public synchronized CommandResult db_command(DB db, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_command(this, db, $0);
        } else {
            this.position = 0;
            return db.command($0);
        }
    }

    @Override
    public synchronized CommandResult db_command(DB db, String $0, ReadPreference $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_command(this, db, $0, $1);
        } else {
            this.position = 0;
            return db.command($0, $1);
        }
    }

    @Override
    public synchronized DBCollection db_createCollection(DB db, String $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_createCollection(this, db, $0, $1);
        } else {
            this.position = 0;
            DBCollection _dbCollection = db.createCollection($0, $1);
            return new DBCollectionWrapper(this.getFilters(), _dbCollection, _dbCollection.getDB(), _dbCollection.getName());
        }
    }

    @Override
    public synchronized DBCollection db_createView(DB db, String $0, String $1, List $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_createView(this, db, $0, $1, $2);
        } else {
            this.position = 0;
            DBCollection _dbCollection = db.createView($0, $1, $2);
            return new DBCollectionWrapper(this.getFilters(), _dbCollection, _dbCollection.getDB(), _dbCollection.getName());
        }
    }

    @Override
    public synchronized DBCollection db_createView(DB db, String $0, String $1, List $2, DBCreateViewOptions $3) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_createView(this, db, $0, $1, $2, $3);
        } else {
            this.position = 0;
            DBCollection _dbCollection = db.createView($0, $1, $2, $3);
            return new DBCollectionWrapper(this.getFilters(), _dbCollection, _dbCollection.getDB(), _dbCollection.getName());
        }
    }

    @Override
    public synchronized CommandResult db_doEval(DB db, String $0, Object[] $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_doEval(this, db, $0, $1);
        } else {
            this.position = 0;
            return db.doEval($0, $1);
        }
    }

    @Override
    public synchronized void db_dropDatabase(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.db_dropDatabase(this, db);
        } else {
            this.position = 0;
            db.dropDatabase();
        }
    }

    @Override
    public synchronized Object db_eval(DB db, String $0, Object[] $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_eval(this, db, $0, $1);
        } else {
            this.position = 0;
            return db.eval($0, $1);
        }
    }

    @Override
    public synchronized DBCollection db_getCollection(DB db, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getCollection(this, db, $0);
        } else {
            this.position = 0;
            DBCollection _dbCollection = db.getCollection($0);
            return new DBCollectionWrapper(this.getFilters(), _dbCollection, _dbCollection.getDB(), _dbCollection.getName());
        }
    }

    @Override
    public synchronized DBCollection db_getCollectionFromString(DB db, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getCollectionFromString(this, db, $0);
        } else {
            this.position = 0;
            DBCollection _dbCollection = db.getCollectionFromString($0);
            return new DBCollectionWrapper(this.getFilters(), _dbCollection, _dbCollection.getDB(), _dbCollection.getName());
        }
    }

    @Override
    public synchronized Set db_getCollectionNames(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getCollectionNames(this, db);
        } else {
            this.position = 0;
            return db.getCollectionNames();
        }
    }

    @Override
    public synchronized Mongo db_getMongo(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getMongo(this, db);
        } else {
            this.position = 0;
            return db.getMongo();
        }
    }

    @Override
    public synchronized String db_getName(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getName(this, db);
        } else {
            this.position = 0;
            return db.getName();
        }
    }

    @Override
    public synchronized int db_getOptions(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getOptions(this, db);
        } else {
            this.position = 0;
            return db.getOptions();
        }
    }

    @Override
    public synchronized ReadConcern db_getReadConcern(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getReadConcern(this, db);
        } else {
            this.position = 0;
            return db.getReadConcern();
        }
    }

    @Override
    public synchronized ReadPreference db_getReadPreference(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getReadPreference(this, db);
        } else {
            this.position = 0;
            return db.getReadPreference();
        }
    }

    @Override
    public synchronized DB db_getSisterDB(DB db, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getSisterDB(this, db, $0);
        } else {
            this.position = 0;
            DB _db = db.getSisterDB($0);
            return new DBWrapper(this.getFilters(), _db, _db.getMongo(), _db.getName());
        }
    }

    @Override
    public synchronized CommandResult db_getStats(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getStats(this, db);
        } else {
            this.position = 0;
            return db.getStats();
        }
    }

    @Override
    public synchronized WriteConcern db_getWriteConcern(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_getWriteConcern(this, db);
        } else {
            this.position = 0;
            return db.getWriteConcern();
        }
    }

    @Override
    public synchronized WriteResult db_removeUser(DB db, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_removeUser(this, db, $0);
        } else {
            this.position = 0;
            return db.removeUser($0);
        }
    }

    @Override
    public synchronized void db_resetOptions(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.db_resetOptions(this, db);
        } else {
            this.position = 0;
            db.resetOptions();
        }
    }

    @Override
    public synchronized void db_setOptions(DB db, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.db_setOptions(this, db, $0);
        } else {
            this.position = 0;
            db.setOptions($0);
        }
    }

    @Override
    public synchronized void db_setReadConcern(DB db, ReadConcern $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.db_setReadConcern(this, db, $0);
        } else {
            this.position = 0;
            db.setReadConcern($0);
        }
    }

    @Override
    public synchronized void db_setReadPreference(DB db, ReadPreference $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.db_setReadPreference(this, db, $0);
        } else {
            this.position = 0;
            db.setReadPreference($0);
        }
    }

    @Override
    public synchronized void db_setWriteConcern(DB db, WriteConcern $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.db_setWriteConcern(this, db, $0);
        } else {
            this.position = 0;
            db.setWriteConcern($0);
        }
    }

    @Override
    public synchronized void db_slaveOk(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.db_slaveOk(this, db);
        } else {
            this.position = 0;
            db.slaveOk();
        }
    }

    @Override
    public synchronized String db_toString(DB db) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.db_toString(this, db);
        } else {
            this.position = 0;
            return db.toString();
        }
    }

    @Override
    public synchronized void dbCollection_addOption(DBCollection dbCollection, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_addOption(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.addOption($0);
        }
    }

    @Override
    public synchronized AggregationOutput dbCollection_aggregate(DBCollection dbCollection, DBObject $0, DBObject[] $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_aggregate(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.aggregate($0, $1);
        }
    }

    @Override
    public synchronized AggregationOutput dbCollection_aggregate(DBCollection dbCollection, List $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_aggregate(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.aggregate($0);
        }
    }

    @Override
    public synchronized AggregationOutput dbCollection_aggregate(DBCollection dbCollection, List $0, ReadPreference $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_aggregate(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.aggregate($0, $1);
        }
    }

    @Override
    public synchronized Cursor dbCollection_aggregate(DBCollection dbCollection, List $0, AggregationOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_aggregate(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.aggregate($0, $1);
        }
    }

    @Override
    public synchronized Cursor dbCollection_aggregate(DBCollection dbCollection, List $0, AggregationOptions $1, ReadPreference $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_aggregate(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.aggregate($0, $1, $2);
        }
    }

    @Override
    public synchronized long dbCollection_count(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_count(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.count();
        }
    }

    @Override
    public synchronized long dbCollection_count(DBCollection dbCollection, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_count(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.count($0);
        }
    }

    @Override
    public synchronized long dbCollection_count(DBCollection dbCollection, DBObject $0, ReadPreference $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_count(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.count($0, $1);
        }
    }

    @Override
    public synchronized long dbCollection_count(DBCollection dbCollection, DBObject $0, DBCollectionCountOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_count(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.count($0, $1);
        }
    }

    @Override
    public synchronized void dbCollection_createIndex(DBCollection dbCollection, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_createIndex(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.createIndex($0);
        }
    }

    @Override
    public synchronized void dbCollection_createIndex(DBCollection dbCollection, DBObject $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_createIndex(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            dbCollection.createIndex($0, $1);
        }
    }

    @Override
    public synchronized void dbCollection_createIndex(DBCollection dbCollection, DBObject $0, String $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_createIndex(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            dbCollection.createIndex($0, $1);
        }
    }

    @Override
    public synchronized void dbCollection_createIndex(DBCollection dbCollection, DBObject $0, String $1, boolean $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_createIndex(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            dbCollection.createIndex($0, $1, $2);
        }
    }

    @Override
    public synchronized void dbCollection_createIndex(DBCollection dbCollection, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_createIndex(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.createIndex($0);
        }
    }

    @Override
    public synchronized List dbCollection_distinct(DBCollection dbCollection, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_distinct(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.distinct($0);
        }
    }

    @Override
    public synchronized List dbCollection_distinct(DBCollection dbCollection, String $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_distinct(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.distinct($0, $1);
        }
    }

    @Override
    public synchronized List dbCollection_distinct(DBCollection dbCollection, String $0, DBObject $1, ReadPreference $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_distinct(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.distinct($0, $1, $2);
        }
    }

    @Override
    public synchronized List dbCollection_distinct(DBCollection dbCollection, String $0, ReadPreference $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_distinct(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.distinct($0, $1);
        }
    }

    @Override
    public synchronized List dbCollection_distinct(DBCollection dbCollection, String $0, DBCollectionDistinctOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_distinct(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.distinct($0, $1);
        }
    }

    @Override
    public synchronized void dbCollection_drop(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_drop(this, dbCollection);
        } else {
            this.position = 0;
            dbCollection.drop();
        }
    }

    @Override
    public synchronized void dbCollection_dropIndex(DBCollection dbCollection, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_dropIndex(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.dropIndex($0);
        }
    }

    @Override
    public synchronized void dbCollection_dropIndex(DBCollection dbCollection, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_dropIndex(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.dropIndex($0);
        }
    }

    @Override
    public synchronized void dbCollection_dropIndexes(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_dropIndexes(this, dbCollection);
        } else {
            this.position = 0;
            dbCollection.dropIndexes();
        }
    }

    @Override
    public synchronized void dbCollection_dropIndexes(DBCollection dbCollection, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_dropIndexes(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.dropIndexes($0);
        }
    }

    @Override
    public synchronized CommandResult dbCollection_explainAggregate(DBCollection dbCollection, List $0, AggregationOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_explainAggregate(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.explainAggregate($0, $1);
        }
    }

    @Override
    public synchronized DBCursor dbCollection_find(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_find(this, dbCollection);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCollection.find();
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCollection_find(DBCollection dbCollection, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_find(this, dbCollection, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCollection.find($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCollection_find(DBCollection dbCollection, DBObject $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_find(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCollection.find($0, $1);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCollection_find(DBCollection dbCollection, DBObject $0, DBObject $1, int $2, int $3) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_find(this, dbCollection, $0, $1, $2, $3);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCollection.find($0, $1, $2, $3);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCollection_find(DBCollection dbCollection, DBObject $0, DBObject $1, int $2, int $3, int $4) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_find(this, dbCollection, $0, $1, $2, $3, $4);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCollection.find($0, $1, $2, $3, $4);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCollection_find(DBCollection dbCollection, DBObject $0, DBCollectionFindOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_find(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCollection.find($0, $1);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndModify(DBCollection dbCollection, DBObject $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndModify(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.findAndModify($0, $1);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndModify(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndModify(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.findAndModify($0, $1, $2);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndModify(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndModify(this, dbCollection, $0, $1, $2, $3, $4, $5, $6);
        } else {
            this.position = 0;
            return dbCollection.findAndModify($0, $1, $2, $3, $4, $5, $6);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndModify(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, boolean $7, long $8, TimeUnit $9) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndModify(this, dbCollection, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9);
        } else {
            this.position = 0;
            return dbCollection.findAndModify($0, $1, $2, $3, $4, $5, $6, $7, $8, $9);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndModify(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, boolean $7, long $8, TimeUnit $9, WriteConcern $10) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndModify(this, dbCollection, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10);
        } else {
            this.position = 0;
            return dbCollection.findAndModify($0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndModify(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, WriteConcern $7) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndModify(this, dbCollection, $0, $1, $2, $3, $4, $5, $6, $7);
        } else {
            this.position = 0;
            return dbCollection.findAndModify($0, $1, $2, $3, $4, $5, $6, $7);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndModify(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, long $7, TimeUnit $8) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndModify(this, dbCollection, $0, $1, $2, $3, $4, $5, $6, $7, $8);
        } else {
            this.position = 0;
            return dbCollection.findAndModify($0, $1, $2, $3, $4, $5, $6, $7, $8);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndModify(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, long $7, TimeUnit $8, WriteConcern $9) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndModify(this, dbCollection, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9);
        } else {
            this.position = 0;
            return dbCollection.findAndModify($0, $1, $2, $3, $4, $5, $6, $7, $8, $9);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndModify(DBCollection dbCollection, DBObject $0, DBCollectionFindAndModifyOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndModify(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.findAndModify($0, $1);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findAndRemove(DBCollection dbCollection, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findAndRemove(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.findAndRemove($0);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findOne(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findOne(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.findOne();
        }
    }

    @Override
    public synchronized DBObject dbCollection_findOne(DBCollection dbCollection, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findOne(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.findOne($0);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findOne(DBCollection dbCollection, DBObject $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findOne(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.findOne($0, $1);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findOne(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findOne(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.findOne($0, $1, $2);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findOne(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, ReadPreference $3) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findOne(this, dbCollection, $0, $1, $2, $3);
        } else {
            this.position = 0;
            return dbCollection.findOne($0, $1, $2, $3);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findOne(DBCollection dbCollection, DBObject $0, DBObject $1, ReadPreference $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findOne(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.findOne($0, $1, $2);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findOne(DBCollection dbCollection, DBObject $0, DBCollectionFindOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findOne(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.findOne($0, $1);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findOne(DBCollection dbCollection, Object $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findOne(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.findOne($0);
        }
    }

    @Override
    public synchronized DBObject dbCollection_findOne(DBCollection dbCollection, Object $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_findOne(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.findOne($0, $1);
        }
    }

    @Override
    public synchronized DBCollection dbCollection_getCollection(DBCollection dbCollection, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getCollection(this, dbCollection, $0);
        } else {
            this.position = 0;
            DBCollection _dbCollection = dbCollection.getCollection($0);
            return new DBCollectionWrapper(this.getFilters(), _dbCollection, _dbCollection.getDB(), _dbCollection.getName());
        }
    }

    @Override
    public synchronized long dbCollection_getCount(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getCount(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getCount();
        }
    }

    @Override
    public synchronized long dbCollection_getCount(DBCollection dbCollection, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getCount(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.getCount($0);
        }
    }

    @Override
    public synchronized long dbCollection_getCount(DBCollection dbCollection, DBObject $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getCount(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.getCount($0, $1);
        }
    }

    @Override
    public synchronized long dbCollection_getCount(DBCollection dbCollection, DBObject $0, DBObject $1, ReadPreference $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getCount(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.getCount($0, $1, $2);
        }
    }

    @Override
    public synchronized long dbCollection_getCount(DBCollection dbCollection, DBObject $0, DBObject $1, long $2, long $3) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getCount(this, dbCollection, $0, $1, $2, $3);
        } else {
            this.position = 0;
            return dbCollection.getCount($0, $1, $2, $3);
        }
    }

    @Override
    public synchronized long dbCollection_getCount(DBCollection dbCollection, DBObject $0, DBObject $1, long $2, long $3, ReadPreference $4) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getCount(this, dbCollection, $0, $1, $2, $3, $4);
        } else {
            this.position = 0;
            return dbCollection.getCount($0, $1, $2, $3, $4);
        }
    }

    @Override
    public synchronized long dbCollection_getCount(DBCollection dbCollection, DBObject $0, DBCollectionCountOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getCount(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.getCount($0, $1);
        }
    }

    @Override
    public synchronized long dbCollection_getCount(DBCollection dbCollection, ReadPreference $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getCount(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.getCount($0);
        }
    }

    @Override
    public synchronized DB dbCollection_getDB(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getDB(this, dbCollection);
        } else {
            this.position = 0;
            DB _db = dbCollection.getDB();
            return new DBWrapper(this.getFilters(), _db, _db.getMongo(), _db.getName());
        }
    }

    @Override
    public synchronized DBDecoderFactory dbCollection_getDBDecoderFactory(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getDBDecoderFactory(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getDBDecoderFactory();
        }
    }

    @Override
    public synchronized DBEncoderFactory dbCollection_getDBEncoderFactory(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getDBEncoderFactory(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getDBEncoderFactory();
        }
    }

    @Override
    public synchronized String dbCollection_getFullName(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getFullName(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getFullName();
        }
    }

    @Override
    public synchronized List dbCollection_getHintFields(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getHintFields(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getHintFields();
        }
    }

    @Override
    public synchronized List dbCollection_getIndexInfo(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getIndexInfo(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getIndexInfo();
        }
    }

    @Override
    public synchronized String dbCollection_getName(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getName(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getName();
        }
    }

    @Override
    public synchronized Class dbCollection_getObjectClass(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getObjectClass(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getObjectClass();
        }
    }

    @Override
    public synchronized int dbCollection_getOptions(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getOptions(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getOptions();
        }
    }

    @Override
    public synchronized ReadConcern dbCollection_getReadConcern(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getReadConcern(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getReadConcern();
        }
    }

    @Override
    public synchronized ReadPreference dbCollection_getReadPreference(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getReadPreference(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getReadPreference();
        }
    }

    @Override
    public synchronized CommandResult dbCollection_getStats(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getStats(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getStats();
        }
    }

    @Override
    public synchronized WriteConcern dbCollection_getWriteConcern(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_getWriteConcern(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.getWriteConcern();
        }
    }

    @Override
    public synchronized DBObject dbCollection_group(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, String $3) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_group(this, dbCollection, $0, $1, $2, $3);
        } else {
            this.position = 0;
            return dbCollection.group($0, $1, $2, $3);
        }
    }

    @Override
    public synchronized DBObject dbCollection_group(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, String $3, String $4) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_group(this, dbCollection, $0, $1, $2, $3, $4);
        } else {
            this.position = 0;
            return dbCollection.group($0, $1, $2, $3, $4);
        }
    }

    @Override
    public synchronized DBObject dbCollection_group(DBCollection dbCollection, DBObject $0, DBObject $1, DBObject $2, String $3, String $4, ReadPreference $5) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_group(this, dbCollection, $0, $1, $2, $3, $4, $5);
        } else {
            this.position = 0;
            return dbCollection.group($0, $1, $2, $3, $4, $5);
        }
    }

    @Override
    public synchronized DBObject dbCollection_group(DBCollection dbCollection, GroupCommand $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_group(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.group($0);
        }
    }

    @Override
    public synchronized DBObject dbCollection_group(DBCollection dbCollection, GroupCommand $0, ReadPreference $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_group(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.group($0, $1);
        }
    }

    @Override
    public synchronized BulkWriteOperation dbCollection_initializeOrderedBulkOperation(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_initializeOrderedBulkOperation(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.initializeOrderedBulkOperation();
        }
    }

    @Override
    public synchronized BulkWriteOperation dbCollection_initializeUnorderedBulkOperation(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_initializeUnorderedBulkOperation(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.initializeUnorderedBulkOperation();
        }
    }

    @Override
    public synchronized WriteResult dbCollection_insert(DBCollection dbCollection, DBObject $0, WriteConcern $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_insert(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.insert($0, $1);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_insert(DBCollection dbCollection, DBObject[] $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_insert(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.insert($0);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_insert(DBCollection dbCollection, DBObject[] $0, WriteConcern $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_insert(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.insert($0, $1);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_insert(DBCollection dbCollection, DBObject[] $0, WriteConcern $1, DBEncoder $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_insert(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.insert($0, $1, $2);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_insert(DBCollection dbCollection, WriteConcern $0, DBObject[] $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_insert(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.insert($0, $1);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_insert(DBCollection dbCollection, List $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_insert(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.insert($0);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_insert(DBCollection dbCollection, List $0, InsertOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_insert(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.insert($0, $1);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_insert(DBCollection dbCollection, List $0, WriteConcern $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_insert(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.insert($0, $1);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_insert(DBCollection dbCollection, List $0, WriteConcern $1, DBEncoder $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_insert(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.insert($0, $1, $2);
        }
    }

    @Override
    public synchronized boolean dbCollection_isCapped(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_isCapped(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.isCapped();
        }
    }

    @Override
    public synchronized MapReduceOutput dbCollection_mapReduce(DBCollection dbCollection, MapReduceCommand $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_mapReduce(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.mapReduce($0);
        }
    }

    @Override
    public synchronized MapReduceOutput dbCollection_mapReduce(DBCollection dbCollection, String $0, String $1, String $2, DBObject $3) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_mapReduce(this, dbCollection, $0, $1, $2, $3);
        } else {
            this.position = 0;
            return dbCollection.mapReduce($0, $1, $2, $3);
        }
    }

    @Override
    public synchronized MapReduceOutput dbCollection_mapReduce(DBCollection dbCollection, String $0, String $1, String $2, OutputType $3, DBObject $4) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_mapReduce(this, dbCollection, $0, $1, $2, $3, $4);
        } else {
            this.position = 0;
            return dbCollection.mapReduce($0, $1, $2, $3, $4);
        }
    }

    @Override
    public synchronized MapReduceOutput dbCollection_mapReduce(DBCollection dbCollection, String $0, String $1, String $2, OutputType $3, DBObject $4, ReadPreference $5) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_mapReduce(this, dbCollection, $0, $1, $2, $3, $4, $5);
        } else {
            this.position = 0;
            return dbCollection.mapReduce($0, $1, $2, $3, $4, $5);
        }
    }

    @Override
    public synchronized List dbCollection_parallelScan(DBCollection dbCollection, ParallelScanOptions $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_parallelScan(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.parallelScan($0);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_remove(DBCollection dbCollection, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_remove(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.remove($0);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_remove(DBCollection dbCollection, DBObject $0, WriteConcern $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_remove(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.remove($0, $1);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_remove(DBCollection dbCollection, DBObject $0, WriteConcern $1, DBEncoder $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_remove(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.remove($0, $1, $2);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_remove(DBCollection dbCollection, DBObject $0, DBCollectionRemoveOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_remove(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.remove($0, $1);
        }
    }

    @Override
    public synchronized DBCollection dbCollection_rename(DBCollection dbCollection, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_rename(this, dbCollection, $0);
        } else {
            this.position = 0;
            DBCollection _dbCollection = dbCollection.rename($0);
            return new DBCollectionWrapper(this.getFilters(), _dbCollection, _dbCollection.getDB(), _dbCollection.getName());
        }
    }

    @Override
    public synchronized DBCollection dbCollection_rename(DBCollection dbCollection, String $0, boolean $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_rename(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            DBCollection _dbCollection = dbCollection.rename($0, $1);
            return new DBCollectionWrapper(this.getFilters(), _dbCollection, _dbCollection.getDB(), _dbCollection.getName());
        }
    }

    @Override
    public synchronized void dbCollection_resetOptions(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_resetOptions(this, dbCollection);
        } else {
            this.position = 0;
            dbCollection.resetOptions();
        }
    }

    @Override
    public synchronized WriteResult dbCollection_save(DBCollection dbCollection, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_save(this, dbCollection, $0);
        } else {
            this.position = 0;
            return dbCollection.save($0);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_save(DBCollection dbCollection, DBObject $0, WriteConcern $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_save(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.save($0, $1);
        }
    }

    @Override
    public synchronized void dbCollection_setDBDecoderFactory(DBCollection dbCollection, DBDecoderFactory $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_setDBDecoderFactory(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.setDBDecoderFactory($0);
        }
    }

    @Override
    public synchronized void dbCollection_setDBEncoderFactory(DBCollection dbCollection, DBEncoderFactory $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_setDBEncoderFactory(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.setDBEncoderFactory($0);
        }
    }

    @Override
    public synchronized void dbCollection_setHintFields(DBCollection dbCollection, List $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_setHintFields(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.setHintFields($0);
        }
    }

    @Override
    public synchronized void dbCollection_setInternalClass(DBCollection dbCollection, String $0, Class $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_setInternalClass(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            dbCollection.setInternalClass($0, $1);
        }
    }

    @Override
    public synchronized void dbCollection_setObjectClass(DBCollection dbCollection, Class $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_setObjectClass(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.setObjectClass($0);
        }
    }

    @Override
    public synchronized void dbCollection_setOptions(DBCollection dbCollection, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_setOptions(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.setOptions($0);
        }
    }

    @Override
    public synchronized void dbCollection_setReadConcern(DBCollection dbCollection, ReadConcern $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_setReadConcern(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.setReadConcern($0);
        }
    }

    @Override
    public synchronized void dbCollection_setReadPreference(DBCollection dbCollection, ReadPreference $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_setReadPreference(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.setReadPreference($0);
        }
    }

    @Override
    public synchronized void dbCollection_setWriteConcern(DBCollection dbCollection, WriteConcern $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_setWriteConcern(this, dbCollection, $0);
        } else {
            this.position = 0;
            dbCollection.setWriteConcern($0);
        }
    }

    @Override
    public synchronized void dbCollection_slaveOk(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCollection_slaveOk(this, dbCollection);
        } else {
            this.position = 0;
            dbCollection.slaveOk();
        }
    }

    @Override
    public synchronized String dbCollection_toString(DBCollection dbCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_toString(this, dbCollection);
        } else {
            this.position = 0;
            return dbCollection.toString();
        }
    }

    @Override
    public synchronized WriteResult dbCollection_update(DBCollection dbCollection, DBObject $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_update(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.update($0, $1);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_update(DBCollection dbCollection, DBObject $0, DBObject $1, boolean $2, boolean $3) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_update(this, dbCollection, $0, $1, $2, $3);
        } else {
            this.position = 0;
            return dbCollection.update($0, $1, $2, $3);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_update(DBCollection dbCollection, DBObject $0, DBObject $1, boolean $2, boolean $3, WriteConcern $4) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_update(this, dbCollection, $0, $1, $2, $3, $4);
        } else {
            this.position = 0;
            return dbCollection.update($0, $1, $2, $3, $4);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_update(DBCollection dbCollection, DBObject $0, DBObject $1, boolean $2, boolean $3, WriteConcern $4, DBEncoder $5) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_update(this, dbCollection, $0, $1, $2, $3, $4, $5);
        } else {
            this.position = 0;
            return dbCollection.update($0, $1, $2, $3, $4, $5);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_update(DBCollection dbCollection, DBObject $0, DBObject $1, boolean $2, boolean $3, WriteConcern $4, Boolean $5, DBEncoder $6) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_update(this, dbCollection, $0, $1, $2, $3, $4, $5, $6);
        } else {
            this.position = 0;
            return dbCollection.update($0, $1, $2, $3, $4, $5, $6);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_update(DBCollection dbCollection, DBObject $0, DBObject $1, DBCollectionUpdateOptions $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_update(this, dbCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return dbCollection.update($0, $1, $2);
        }
    }

    @Override
    public synchronized WriteResult dbCollection_updateMulti(DBCollection dbCollection, DBObject $0, DBObject $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCollection_updateMulti(this, dbCollection, $0, $1);
        } else {
            this.position = 0;
            return dbCollection.updateMulti($0, $1);
        }
    }

    @Override
    public synchronized void mongoDatabase_createCollection(MongoDatabase mongoDatabase, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoDatabase_createCollection(this, mongoDatabase, $0);
        } else {
            this.position = 0;
            mongoDatabase.createCollection($0);
        }
    }

    @Override
    public synchronized void mongoDatabase_createCollection(MongoDatabase mongoDatabase, String $0, CreateCollectionOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoDatabase_createCollection(this, mongoDatabase, $0, $1);
        } else {
            this.position = 0;
            mongoDatabase.createCollection($0, $1);
        }
    }

    @Override
    public synchronized void mongoDatabase_createView(MongoDatabase mongoDatabase, String $0, String $1, List $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoDatabase_createView(this, mongoDatabase, $0, $1, $2);
        } else {
            this.position = 0;
            mongoDatabase.createView($0, $1, $2);
        }
    }

    @Override
    public synchronized void mongoDatabase_createView(MongoDatabase mongoDatabase, String $0, String $1, List $2, CreateViewOptions $3) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoDatabase_createView(this, mongoDatabase, $0, $1, $2, $3);
        } else {
            this.position = 0;
            mongoDatabase.createView($0, $1, $2, $3);
        }
    }

    @Override
    public synchronized void mongoDatabase_drop(MongoDatabase mongoDatabase) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoDatabase_drop(this, mongoDatabase);
        } else {
            this.position = 0;
            mongoDatabase.drop();
        }
    }

    @Override
    public synchronized CodecRegistry mongoDatabase_getCodecRegistry(MongoDatabase mongoDatabase) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_getCodecRegistry(this, mongoDatabase);
        } else {
            this.position = 0;
            return mongoDatabase.getCodecRegistry();
        }
    }

    @Override
    public synchronized MongoCollection mongoDatabase_getCollection(MongoDatabase mongoDatabase, String $0, Class $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_getCollection(this, mongoDatabase, $0, $1);
        } else {
            this.position = 0;
            return new MongoCollectionWrapper(this.getFilters(), mongoDatabase.getCollection($0, $1));
        }
    }

    @Override
    public synchronized MongoCollection mongoDatabase_getCollection(MongoDatabase mongoDatabase, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_getCollection(this, mongoDatabase, $0);
        } else {
            this.position = 0;
            return new MongoCollectionWrapper(this.getFilters(), mongoDatabase.getCollection($0));
        }
    }

    @Override
    public synchronized String mongoDatabase_getName(MongoDatabase mongoDatabase) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_getName(this, mongoDatabase);
        } else {
            this.position = 0;
            return mongoDatabase.getName();
        }
    }

    @Override
    public synchronized ReadConcern mongoDatabase_getReadConcern(MongoDatabase mongoDatabase) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_getReadConcern(this, mongoDatabase);
        } else {
            this.position = 0;
            return mongoDatabase.getReadConcern();
        }
    }

    @Override
    public synchronized ReadPreference mongoDatabase_getReadPreference(MongoDatabase mongoDatabase) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_getReadPreference(this, mongoDatabase);
        } else {
            this.position = 0;
            return mongoDatabase.getReadPreference();
        }
    }

    @Override
    public synchronized WriteConcern mongoDatabase_getWriteConcern(MongoDatabase mongoDatabase) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_getWriteConcern(this, mongoDatabase);
        } else {
            this.position = 0;
            return mongoDatabase.getWriteConcern();
        }
    }

    @Override
    public synchronized MongoIterable mongoDatabase_listCollectionNames(MongoDatabase mongoDatabase) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_listCollectionNames(this, mongoDatabase);
        } else {
            this.position = 0;
            return mongoDatabase.listCollectionNames();
        }
    }

    @Override
    public synchronized ListCollectionsIterable mongoDatabase_listCollections(MongoDatabase mongoDatabase, Class $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_listCollections(this, mongoDatabase, $0);
        } else {
            this.position = 0;
            return mongoDatabase.listCollections($0);
        }
    }

    @Override
    public synchronized ListCollectionsIterable mongoDatabase_listCollections(MongoDatabase mongoDatabase) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_listCollections(this, mongoDatabase);
        } else {
            this.position = 0;
            return mongoDatabase.listCollections();
        }
    }

    @Override
    public synchronized Object mongoDatabase_runCommand(MongoDatabase mongoDatabase, Bson $0, ReadPreference $1, Class $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_runCommand(this, mongoDatabase, $0, $1, $2);
        } else {
            this.position = 0;
            return mongoDatabase.runCommand($0, $1, $2);
        }
    }

    @Override
    public synchronized Object mongoDatabase_runCommand(MongoDatabase mongoDatabase, Bson $0, Class $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_runCommand(this, mongoDatabase, $0, $1);
        } else {
            this.position = 0;
            return mongoDatabase.runCommand($0, $1);
        }
    }

    @Override
    public synchronized Document mongoDatabase_runCommand(MongoDatabase mongoDatabase, Bson $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_runCommand(this, mongoDatabase, $0);
        } else {
            this.position = 0;
            return mongoDatabase.runCommand($0);
        }
    }

    @Override
    public synchronized Document mongoDatabase_runCommand(MongoDatabase mongoDatabase, Bson $0, ReadPreference $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_runCommand(this, mongoDatabase, $0, $1);
        } else {
            this.position = 0;
            return mongoDatabase.runCommand($0, $1);
        }
    }

    @Override
    public synchronized MongoDatabase mongoDatabase_withCodecRegistry(MongoDatabase mongoDatabase, CodecRegistry $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_withCodecRegistry(this, mongoDatabase, $0);
        } else {
            this.position = 0;
            return new MongoDatabaseWrapper(this.getFilters(), mongoDatabase.withCodecRegistry($0));
        }
    }

    @Override
    public synchronized MongoDatabase mongoDatabase_withReadConcern(MongoDatabase mongoDatabase, ReadConcern $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_withReadConcern(this, mongoDatabase, $0);
        } else {
            this.position = 0;
            return new MongoDatabaseWrapper(this.getFilters(), mongoDatabase.withReadConcern($0));
        }
    }

    @Override
    public synchronized MongoDatabase mongoDatabase_withReadPreference(MongoDatabase mongoDatabase, ReadPreference $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_withReadPreference(this, mongoDatabase, $0);
        } else {
            this.position = 0;
            return new MongoDatabaseWrapper(this.getFilters(), mongoDatabase.withReadPreference($0));
        }
    }

    @Override
    public synchronized MongoDatabase mongoDatabase_withWriteConcern(MongoDatabase mongoDatabase, WriteConcern $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoDatabase_withWriteConcern(this, mongoDatabase, $0);
        } else {
            this.position = 0;
            return new MongoDatabaseWrapper(this.getFilters(), mongoDatabase.withWriteConcern($0));
        }
    }

    @Override
    public synchronized DBCursor dbCursor_addOption(DBCursor dbCursor, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_addOption(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.addOption($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_addSpecial(DBCursor dbCursor, String $0, Object $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_addSpecial(this, dbCursor, $0, $1);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.addSpecial($0, $1);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_batchSize(DBCursor dbCursor, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_batchSize(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.batchSize($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized void dbCursor_close(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCursor_close(this, dbCursor);
        } else {
            this.position = 0;
            dbCursor.close();
        }
    }

    @Override
    public synchronized DBCursor dbCursor_comment(DBCursor dbCursor, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_comment(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.comment($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_copy(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_copy(this, dbCursor);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.copy();
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized int dbCursor_count(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_count(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.count();
        }
    }

    @Override
    public synchronized DBObject dbCursor_curr(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_curr(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.curr();
        }
    }

    @Override
    public synchronized DBObject dbCursor_explain(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_explain(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.explain();
        }
    }

    @Override
    public synchronized void dbCursor_forEach(DBCursor dbCursor, Consumer $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCursor_forEach(this, dbCursor, $0);
        } else {
            this.position = 0;
            dbCursor.forEach($0);
        }
    }

    @Override
    public synchronized void dbCursor_forEachRemaining(DBCursor dbCursor, Consumer $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCursor_forEachRemaining(this, dbCursor, $0);
        } else {
            this.position = 0;
            dbCursor.forEachRemaining($0);
        }
    }

    @Override
    public synchronized int dbCursor_getBatchSize(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getBatchSize(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getBatchSize();
        }
    }

    @Override
    public synchronized Collation dbCursor_getCollation(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getCollation(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getCollation();
        }
    }

    @Override
    public synchronized DBCollection dbCursor_getCollection(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getCollection(this, dbCursor);
        } else {
            this.position = 0;
            DBCollection _dbCollection = dbCursor.getCollection();
            return new DBCollectionWrapper(this.getFilters(), _dbCollection, _dbCollection.getDB(), _dbCollection.getName());
        }
    }

    @Override
    public synchronized long dbCursor_getCursorId(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getCursorId(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getCursorId();
        }
    }

    @Override
    public synchronized DBDecoderFactory dbCursor_getDecoderFactory(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getDecoderFactory(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getDecoderFactory();
        }
    }

    @Override
    public synchronized DBObject dbCursor_getKeysWanted(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getKeysWanted(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getKeysWanted();
        }
    }

    @Override
    public synchronized int dbCursor_getLimit(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getLimit(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getLimit();
        }
    }

    @Override
    public synchronized int dbCursor_getOptions(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getOptions(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getOptions();
        }
    }

    @Override
    public synchronized DBObject dbCursor_getQuery(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getQuery(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getQuery();
        }
    }

    @Override
    public synchronized ReadPreference dbCursor_getReadPreference(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getReadPreference(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getReadPreference();
        }
    }

    @Override
    public synchronized ServerAddress dbCursor_getServerAddress(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_getServerAddress(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.getServerAddress();
        }
    }

    @Override
    public synchronized boolean dbCursor_hasNext(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_hasNext(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.hasNext();
        }
    }

    @Override
    public synchronized DBCursor dbCursor_hint(DBCursor dbCursor, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_hint(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.hint($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_hint(DBCursor dbCursor, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_hint(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.hint($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized int dbCursor_itcount(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_itcount(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.itcount();
        }
    }

    @Override
    public synchronized Iterator dbCursor_iterator(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_iterator(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.iterator();
        }
    }

    @Override
    public synchronized int dbCursor_length(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_length(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.length();
        }
    }

    @Override
    public synchronized DBCursor dbCursor_limit(DBCursor dbCursor, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_limit(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.limit($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_max(DBCursor dbCursor, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_max(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.max($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_maxScan(DBCursor dbCursor, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_maxScan(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.maxScan($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_maxTime(DBCursor dbCursor, long $0, TimeUnit $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_maxTime(this, dbCursor, $0, $1);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.maxTime($0, $1);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_min(DBCursor dbCursor, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_min(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.min($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBObject dbCursor_next(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_next(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.next();
        }
    }

    @Override
    public synchronized int dbCursor_numSeen(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_numSeen(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.numSeen();
        }
    }

    @Override
    public synchronized DBObject dbCursor_one(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_one(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.one();
        }
    }

    @Override
    public synchronized void dbCursor_remove(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.dbCursor_remove(this, dbCursor);
        } else {
            this.position = 0;
            dbCursor.remove();
        }
    }

    @Override
    public synchronized DBCursor dbCursor_resetOptions(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_resetOptions(this, dbCursor);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.resetOptions();
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_returnKey(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_returnKey(this, dbCursor);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.returnKey();
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_setCollation(DBCursor dbCursor, Collation $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_setCollation(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.setCollation($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_setDecoderFactory(DBCursor dbCursor, DBDecoderFactory $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_setDecoderFactory(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.setDecoderFactory($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_setOptions(DBCursor dbCursor, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_setOptions(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.setOptions($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_setReadPreference(DBCursor dbCursor, ReadPreference $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_setReadPreference(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.setReadPreference($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_showDiskLoc(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_showDiskLoc(this, dbCursor);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.showDiskLoc();
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized int dbCursor_size(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_size(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.size();
        }
    }

    @Override
    public synchronized DBCursor dbCursor_skip(DBCursor dbCursor, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_skip(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.skip($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_slaveOk(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_slaveOk(this, dbCursor);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.slaveOk();
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_snapshot(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_snapshot(this, dbCursor);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.snapshot();
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized DBCursor dbCursor_sort(DBCursor dbCursor, DBObject $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_sort(this, dbCursor, $0);
        } else {
            this.position = 0;
            DBCursor _dbCursor = dbCursor.sort($0);
            return new DBCursorWrapper(this.getFilters(), _dbCursor, _dbCursor.getCollection(), null, null, null);
        }
    }

    @Override
    public synchronized Spliterator dbCursor_spliterator(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_spliterator(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.spliterator();
        }
    }

    @Override
    public synchronized List dbCursor_toArray(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_toArray(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.toArray();
        }
    }

    @Override
    public synchronized List dbCursor_toArray(DBCursor dbCursor, int $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_toArray(this, dbCursor, $0);
        } else {
            this.position = 0;
            return dbCursor.toArray($0);
        }
    }

    @Override
    public synchronized String dbCursor_toString(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_toString(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.toString();
        }
    }

    @Override
    public synchronized DBObject dbCursor_tryNext(DBCursor dbCursor) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.dbCursor_tryNext(this, dbCursor);
        } else {
            this.position = 0;
            return dbCursor.tryNext();
        }
    }

    @Override
    public synchronized AggregateIterable mongoCollection_aggregate(MongoCollection mongoCollection, List $0, Class $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_aggregate(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.aggregate($0, $1);
        }
    }

    @Override
    public synchronized AggregateIterable mongoCollection_aggregate(MongoCollection mongoCollection, List $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_aggregate(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.aggregate($0);
        }
    }

    @Override
    public synchronized BulkWriteResult mongoCollection_bulkWrite(MongoCollection mongoCollection, List $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_bulkWrite(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.bulkWrite($0);
        }
    }

    @Override
    public synchronized BulkWriteResult mongoCollection_bulkWrite(MongoCollection mongoCollection, List $0, BulkWriteOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_bulkWrite(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.bulkWrite($0, $1);
        }
    }

    @Override
    public synchronized long mongoCollection_count(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_count(this, mongoCollection);
        } else {
            this.position = 0;
            return mongoCollection.count();
        }
    }

    @Override
    public synchronized long mongoCollection_count(MongoCollection mongoCollection, Bson $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_count(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.count($0);
        }
    }

    @Override
    public synchronized long mongoCollection_count(MongoCollection mongoCollection, Bson $0, CountOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_count(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.count($0, $1);
        }
    }

    @Override
    public synchronized String mongoCollection_createIndex(MongoCollection mongoCollection, Bson $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_createIndex(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.createIndex($0);
        }
    }

    @Override
    public synchronized String mongoCollection_createIndex(MongoCollection mongoCollection, Bson $0, IndexOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_createIndex(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.createIndex($0, $1);
        }
    }

    @Override
    public synchronized List mongoCollection_createIndexes(MongoCollection mongoCollection, List $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_createIndexes(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.createIndexes($0);
        }
    }

    @Override
    public synchronized DeleteResult mongoCollection_deleteMany(MongoCollection mongoCollection, Bson $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_deleteMany(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.deleteMany($0);
        }
    }

    @Override
    public synchronized DeleteResult mongoCollection_deleteMany(MongoCollection mongoCollection, Bson $0, DeleteOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_deleteMany(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.deleteMany($0, $1);
        }
    }

    @Override
    public synchronized DeleteResult mongoCollection_deleteOne(MongoCollection mongoCollection, Bson $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_deleteOne(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.deleteOne($0);
        }
    }

    @Override
    public synchronized DeleteResult mongoCollection_deleteOne(MongoCollection mongoCollection, Bson $0, DeleteOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_deleteOne(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.deleteOne($0, $1);
        }
    }

    @Override
    public synchronized DistinctIterable mongoCollection_distinct(MongoCollection mongoCollection, String $0, Class $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_distinct(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.distinct($0, $1);
        }
    }

    @Override
    public synchronized DistinctIterable mongoCollection_distinct(MongoCollection mongoCollection, String $0, Bson $1, Class $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_distinct(this, mongoCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return mongoCollection.distinct($0, $1, $2);
        }
    }

    @Override
    public synchronized void mongoCollection_drop(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_drop(this, mongoCollection);
        } else {
            this.position = 0;
            mongoCollection.drop();
        }
    }

    @Override
    public synchronized void mongoCollection_dropIndex(MongoCollection mongoCollection, String $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_dropIndex(this, mongoCollection, $0);
        } else {
            this.position = 0;
            mongoCollection.dropIndex($0);
        }
    }

    @Override
    public synchronized void mongoCollection_dropIndex(MongoCollection mongoCollection, Bson $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_dropIndex(this, mongoCollection, $0);
        } else {
            this.position = 0;
            mongoCollection.dropIndex($0);
        }
    }

    @Override
    public synchronized void mongoCollection_dropIndexes(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_dropIndexes(this, mongoCollection);
        } else {
            this.position = 0;
            mongoCollection.dropIndexes();
        }
    }

    @Override
    public synchronized FindIterable mongoCollection_find(MongoCollection mongoCollection, Class $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_find(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.find($0);
        }
    }

    @Override
    public synchronized FindIterable mongoCollection_find(MongoCollection mongoCollection, Bson $0, Class $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_find(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.find($0, $1);
        }
    }

    @Override
    public synchronized FindIterable mongoCollection_find(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_find(this, mongoCollection);
        } else {
            this.position = 0;
            return mongoCollection.find();
        }
    }

    @Override
    public synchronized FindIterable mongoCollection_find(MongoCollection mongoCollection, Bson $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_find(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.find($0);
        }
    }

    @Override
    public synchronized Object mongoCollection_findOneAndDelete(MongoCollection mongoCollection, Bson $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_findOneAndDelete(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.findOneAndDelete($0);
        }
    }

    @Override
    public synchronized Object mongoCollection_findOneAndDelete(MongoCollection mongoCollection, Bson $0, FindOneAndDeleteOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_findOneAndDelete(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.findOneAndDelete($0, $1);
        }
    }

    @Override
    public synchronized Object mongoCollection_findOneAndReplace(MongoCollection mongoCollection, Bson $0, Object $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_findOneAndReplace(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.findOneAndReplace($0, $1);
        }
    }

    @Override
    public synchronized Object mongoCollection_findOneAndReplace(MongoCollection mongoCollection, Bson $0, Object $1, FindOneAndReplaceOptions $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_findOneAndReplace(this, mongoCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return mongoCollection.findOneAndReplace($0, $1, $2);
        }
    }

    @Override
    public synchronized Object mongoCollection_findOneAndUpdate(MongoCollection mongoCollection, Bson $0, Bson $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_findOneAndUpdate(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.findOneAndUpdate($0, $1);
        }
    }

    @Override
    public synchronized Object mongoCollection_findOneAndUpdate(MongoCollection mongoCollection, Bson $0, Bson $1, FindOneAndUpdateOptions $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_findOneAndUpdate(this, mongoCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return mongoCollection.findOneAndUpdate($0, $1, $2);
        }
    }

    @Override
    public synchronized CodecRegistry mongoCollection_getCodecRegistry(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_getCodecRegistry(this, mongoCollection);
        } else {
            this.position = 0;
            return mongoCollection.getCodecRegistry();
        }
    }

    @Override
    public synchronized Class mongoCollection_getDocumentClass(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_getDocumentClass(this, mongoCollection);
        } else {
            this.position = 0;
            return mongoCollection.getDocumentClass();
        }
    }

    @Override
    public synchronized MongoNamespace mongoCollection_getNamespace(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_getNamespace(this, mongoCollection);
        } else {
            this.position = 0;
            return mongoCollection.getNamespace();
        }
    }

    @Override
    public synchronized ReadConcern mongoCollection_getReadConcern(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_getReadConcern(this, mongoCollection);
        } else {
            this.position = 0;
            return mongoCollection.getReadConcern();
        }
    }

    @Override
    public synchronized ReadPreference mongoCollection_getReadPreference(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_getReadPreference(this, mongoCollection);
        } else {
            this.position = 0;
            return mongoCollection.getReadPreference();
        }
    }

    @Override
    public synchronized WriteConcern mongoCollection_getWriteConcern(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_getWriteConcern(this, mongoCollection);
        } else {
            this.position = 0;
            return mongoCollection.getWriteConcern();
        }
    }

    @Override
    public synchronized void mongoCollection_insertMany(MongoCollection mongoCollection, List $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_insertMany(this, mongoCollection, $0);
        } else {
            this.position = 0;
            mongoCollection.insertMany($0);
        }
    }

    @Override
    public synchronized void mongoCollection_insertMany(MongoCollection mongoCollection, List $0, InsertManyOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_insertMany(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            mongoCollection.insertMany($0, $1);
        }
    }

    @Override
    public synchronized void mongoCollection_insertOne(MongoCollection mongoCollection, Object $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_insertOne(this, mongoCollection, $0);
        } else {
            this.position = 0;
            mongoCollection.insertOne($0);
        }
    }

    @Override
    public synchronized void mongoCollection_insertOne(MongoCollection mongoCollection, Object $0, InsertOneOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_insertOne(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            mongoCollection.insertOne($0, $1);
        }
    }

    @Override
    public synchronized ListIndexesIterable mongoCollection_listIndexes(MongoCollection mongoCollection, Class $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_listIndexes(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return mongoCollection.listIndexes($0);
        }
    }

    @Override
    public synchronized ListIndexesIterable mongoCollection_listIndexes(MongoCollection mongoCollection) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_listIndexes(this, mongoCollection);
        } else {
            this.position = 0;
            return mongoCollection.listIndexes();
        }
    }

    @Override
    public synchronized MapReduceIterable mongoCollection_mapReduce(MongoCollection mongoCollection, String $0, String $1, Class $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_mapReduce(this, mongoCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return mongoCollection.mapReduce($0, $1, $2);
        }
    }

    @Override
    public synchronized MapReduceIterable mongoCollection_mapReduce(MongoCollection mongoCollection, String $0, String $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_mapReduce(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.mapReduce($0, $1);
        }
    }

    @Override
    public synchronized void mongoCollection_renameCollection(MongoCollection mongoCollection, MongoNamespace $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_renameCollection(this, mongoCollection, $0);
        } else {
            this.position = 0;
            mongoCollection.renameCollection($0);
        }
    }

    @Override
    public synchronized void mongoCollection_renameCollection(MongoCollection mongoCollection, MongoNamespace $0, RenameCollectionOptions $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            nextFilter.mongoCollection_renameCollection(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            mongoCollection.renameCollection($0, $1);
        }
    }

    @Override
    public synchronized UpdateResult mongoCollection_replaceOne(MongoCollection mongoCollection, Bson $0, Object $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_replaceOne(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.replaceOne($0, $1);
        }
    }

    @Override
    public synchronized UpdateResult mongoCollection_replaceOne(MongoCollection mongoCollection, Bson $0, Object $1, UpdateOptions $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_replaceOne(this, mongoCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return mongoCollection.replaceOne($0, $1, $2);
        }
    }

    @Override
    public synchronized UpdateResult mongoCollection_updateMany(MongoCollection mongoCollection, Bson $0, Bson $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_updateMany(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.updateMany($0, $1);
        }
    }

    @Override
    public synchronized UpdateResult mongoCollection_updateMany(MongoCollection mongoCollection, Bson $0, Bson $1, UpdateOptions $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_updateMany(this, mongoCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return mongoCollection.updateMany($0, $1, $2);
        }
    }

    @Override
    public synchronized UpdateResult mongoCollection_updateOne(MongoCollection mongoCollection, Bson $0, Bson $1) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_updateOne(this, mongoCollection, $0, $1);
        } else {
            this.position = 0;
            return mongoCollection.updateOne($0, $1);
        }
    }

    @Override
    public synchronized UpdateResult mongoCollection_updateOne(MongoCollection mongoCollection, Bson $0, Bson $1, UpdateOptions $2) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_updateOne(this, mongoCollection, $0, $1, $2);
        } else {
            this.position = 0;
            return mongoCollection.updateOne($0, $1, $2);
        }
    }

    @Override
    public synchronized MongoCollection mongoCollection_withCodecRegistry(MongoCollection mongoCollection, CodecRegistry $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_withCodecRegistry(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return new MongoCollectionWrapper(this.getFilters(), mongoCollection.withCodecRegistry($0));
        }
    }

    @Override
    public synchronized MongoCollection mongoCollection_withDocumentClass(MongoCollection mongoCollection, Class $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_withDocumentClass(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return new MongoCollectionWrapper(this.getFilters(), mongoCollection.withDocumentClass($0));
        }
    }

    @Override
    public synchronized MongoCollection mongoCollection_withReadConcern(MongoCollection mongoCollection, ReadConcern $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_withReadConcern(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return new MongoCollectionWrapper(this.getFilters(), mongoCollection.withReadConcern($0));
        }
    }

    @Override
    public synchronized MongoCollection mongoCollection_withReadPreference(MongoCollection mongoCollection, ReadPreference $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_withReadPreference(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return new MongoCollectionWrapper(this.getFilters(), mongoCollection.withReadPreference($0));
        }
    }

    @Override
    public synchronized MongoCollection mongoCollection_withWriteConcern(MongoCollection mongoCollection, WriteConcern $0) {
        if (this.position < this.getFilters().size()) {
            MongoFilter nextFilter = this.getFilters().get(this.position++);
            return nextFilter.mongoCollection_withWriteConcern(this, mongoCollection, $0);
        } else {
            this.position = 0;
            return new MongoCollectionWrapper(this.getFilters(), mongoCollection.withWriteConcern($0));
        }
    }

}